package com.sport.service.impl;

import com.sport.entity.Productlabeling;
import com.sport.entity.ProductTag;
import com.sport.mapper.ProductlabelingMapper;
import com.sport.mapper.ProductTagMapper;
import com.sport.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sport.annotation.TagField;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductTagMapper productTagMapper;

    @Autowired
    private ProductlabelingMapper productLabelingMapper;

    @Override
    public List<ProductTag> getProductTagsByProductName(String productName) {
        return productTagMapper.selectByProductName(productName);
    }


    @Override
    public Productlabeling getProductLabelingByName(String productName) {
        return productLabelingMapper.selectByName(productName);
    }

    @Override
    public Map<String, String> getCrownProductTagsByProductName(String productName) {
        // 获取所有与 productName 相关的产品标签
        List<ProductTag> productTags = productTagMapper.selectByProductName(productName);

        // 使用反射构建 fieldMapping 和 displayNameMapping
        Map<String, Function<ProductTag, Integer>> fieldMapping = new HashMap<>();
        Map<String, String> displayNameMapping = new HashMap<>();
        buildFieldMapping(ProductTag.class, fieldMapping, displayNameMapping);

        // 统计每个字段中 1 出现的次数
        int totalRecords = productTags.size();
        Map<String, Integer> countMap = new HashMap<>();

        for (Map.Entry<String, Function<ProductTag, Integer>> entry : fieldMapping.entrySet()) {
            String fieldName = entry.getKey();
            Function<ProductTag, Integer> getter = entry.getValue();

            for (ProductTag tag : productTags) {
                Integer value = getter.apply(tag);
                if (value != null && value == 1) {
                    countMap.put(fieldName, countMap.getOrDefault(fieldName, 0) + 1);
                }
            }
        }

        // 计算每个字段的比例，并筛选出比例 >= 80% 的字段
        Map<String, String> result = new HashMap<>();
        double threshold = 0.8;
        for (Map.Entry<String, Integer> entry : countMap.entrySet()) {
            if ((double) entry.getValue() / totalRecords >= threshold) {
                // 使用字段名作为键，显示名称作为值
                String fieldName = entry.getKey();
                String displayName = displayNameMapping.get(fieldName);
                result.put(fieldName, displayName);
            }
        }

        return result;
    }

    /**
     * 构建产品标签类的字段映射
     * 该方法反射ProductTag类中的每个字段，并使用TagField注解来确定字段的显示名称
     * 同时，它生成一个函数映射，用于根据字段名获取对应的值
     *
     * @param clazz 产品标签类的类型
     * @param fieldMapping 字段名到Function的映射
     * @param displayNameMapping 字段名到显示名称的映射
     */
    private void buildFieldMapping(Class<ProductTag> clazz, Map<String, Function<ProductTag, Integer>> fieldMapping, Map<String, String> displayNameMapping) {
        // 获取ProductTag类的所有字段
        Field[] fields = clazz.getDeclaredFields();

        // 遍历每个字段
        for (Field field : fields) {
            // 获取字段上的TagField注解
            TagField annotation = field.getAnnotation(TagField.class);
            // 如果字段上有TagField注解
            if (annotation != null) {
                // 获取注解中的显示名称
                String displayName = annotation.displayName();
                // 根据字段名生成getter方法名
                String methodName = "get" + capitalize(field.getName());
                try {
                    // 获取对应的getter方法
                    Method method = clazz.getMethod(methodName);
                    // 创建一个函数，用于调用getter方法获取字段值
                    Function<ProductTag, Integer> getter = tag -> {
                        try {
                            return (Integer) method.invoke(tag);
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    };
                    // 将字段名和对应的getter函数放入映射中
                    fieldMapping.put(field.getName(), getter);
                    // 将字段名和显示名称放入映射中
                    displayNameMapping.put(field.getName(), displayName);
                } catch (NoSuchMethodException e) {
                    // 如果未找到getter方法，抛出运行时异常
                    throw new RuntimeException("未找到字段的Getter方法: " + field.getName(), e);
                }
            }
        }
    }

    /**
     * 将字符串的首字母大写
     *
     * @param str 待处理的字符串
     * @return 首字母大写后的字符串，如果输入为空或null，则返回原值
     */
    private String capitalize(String str) {
        // 检查输入字符串是否为null或空，如果是，则直接返回
        if (str == null || str.isEmpty()) {
            return str;
        }
        // 将字符串的首字母大写，并将其余部分保持不变
        return Character.toUpperCase(str.charAt(0)) + str.substring(1);
    }
}
